﻿using System;
using System.IO;
using System.Text;
using System.Threading;
using RpcHelper.TaskTools;
namespace RpcHelper.Config
{
    /// <summary>
    /// 本地配置项
    /// </summary>
    internal class LocalConfigCollect : ConfigCollect
    {
        private readonly FileInfo _File = null;
        private Timer _SaveTimer;
        private Timer _RefreshTimer;
        private readonly DateTime _LastWriteTime;
        private ConfigSet _Config;
        private volatile bool _IsUpdate = false;
        public LocalConfigCollect(string path) : base()
        {
            this.RefreshEvent += this._RefreshEvent;
            this._File = new FileInfo(path);
            if (this._File.Exists)
            {
                this._LastWriteTime = this._File.LastWriteTime;
                string json = Tools.ReadText(path, Encoding.UTF8, false);
                if (!string.IsNullOrEmpty(json))
                {
                    this._Init(Tools.CompressJson(json), 10);
                }
            }
            this._Config = this.GetValue<ConfigSet>("local:config", new ConfigSet());
            if (this._Config.AutoLoad)
            {
                int time = this._Config.CheckTime * 1000;
                this._RefreshTimer = new Timer(this._Refresh, null, time, time);
            }
            if (this._Config.AutoSave)
            {
                int time = this._Config.SaveTime * 1000;
                this._SaveTimer = new Timer(this._SaveFile, null, time, time);
            }
        }
        private void _SaveFile(object _)
        {
            if (!this._IsUpdate)
            {
                return;
            }
            base.SaveFile(this._File);
        }
        public void SaveFile()
        {
            base.SaveFile(this._File);
        }

        private void _InitAutoLoad(ConfigSet set)
        {
            if (set.AutoLoad && !this._Config.AutoLoad)
            {
                int time = set.CheckTime * 1000;
                this._RefreshTimer = new Timer(this._Refresh, null, time, time);
            }
            else if (!set.AutoLoad && this._Config.AutoLoad)
            {
                this._RefreshTimer.Dispose();
            }
            else if (set.AutoLoad && set.CheckTime != this._Config.CheckTime)
            {
                int time = set.CheckTime * 1000;
                this._RefreshTimer.Change(time, time);
            }
        }
        private void _InitAutoSave(ConfigSet set)
        {
            if (set.AutoSave && !this._Config.AutoSave)
            {
                int time = set.SaveTime * 1000;
                this._SaveTimer = new Timer(this._SaveFile, null, time, time);
            }
            else if (!set.AutoSave && this._Config.AutoSave)
            {
                this._SaveTimer.Dispose();
            }
            else if (set.AutoSave && set.SaveTime != this._Config.SaveTime)
            {
                int time = set.SaveTime * 1000;
                this._SaveTimer.Change(time, time);
            }
        }
        private void _RefreshEvent(IConfigCollect config, string name)
        {
            this._IsUpdate = true;
            if (name == "local:config" || name.StartsWith("local:config:"))
            {
                ConfigSet set = this.GetValue<ConfigSet>("local:config", new ConfigSet());
                _InitAutoLoad(set);
                _InitAutoSave(set);
                this._Config = set;
            }
        }

        private void _Refresh(object _)
        {
            this._File.Refresh();
            if (!this._File.Exists || this._File.LastWriteTime <= this._LastWriteTime)
            {
                return;
            }
            string json = Tools.ReadText(this._File, Encoding.UTF8, true);
            if (string.IsNullOrEmpty(json))
            {
                return;
            }
            this._Set(json, this._Config.Prower);
        }
    }
}
